package com.study.thread.juc.lock;


import java.util.Arrays;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionDemo1 {

    private Integer[] integerArr = new Integer[15];

    int putIndex = 0;

    int putCount = 0;

    int getIndex = 0;

    int getCount = 0;

    private Lock lock = new ReentrantLock();

    private Condition putCodition = lock.newCondition();
    private Condition getCodition = lock.newCondition();

    public static void main(String[] args) throws InterruptedException {
        ConditionDemo1 conditionDemo1 = new ConditionDemo1();

        for (int i = 0; i < 50; i++) {
            new Thread(() -> {
                conditionDemo1.getValue();
            }).start();
        }

        for (int i = 0; i < 50; i++) {
            new Thread(() -> {
                conditionDemo1.putValue();
            }).start();
        }

    }

    // 填充
    private void putValue() {
        try {
            lock.lock();
            // 有元素则等待，等待消费者消费，在继续填充
            while (integerArr[putIndex] != null) {
                putCodition.await();
            }

            integerArr[putIndex++] = putIndex; //填充当前元素
            // 填充下标是否要越界，从0开始继续填充内容
            if (putIndex == integerArr.length) {
                putIndex = 0;
            }
            putCount++; // 记录填充操作数
            getCodition.signal(); // 唤醒睡眠的消费者起来消费
            System.out.println("put ："+ Arrays.toString(integerArr));
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    // 获取
    private void getValue() {
        try {
            lock.lock();

            // 判断当前数组获取下标是否有内容，没内容就相当于没有填充值，则进行等待生产者唤醒
            while (integerArr[getIndex] == null) {
                getCodition.await();
            }
            integerArr[getIndex++] = null; // 弹出当前获取的内容

            // 判断当前获取的数组长度是否超出，超出从0开始继续获取
            if (getIndex == integerArr.length) {
                getIndex = 0;
            }
            getCount++; //当前操作记录数，主要为了判断是否和
            putCodition.signal(); // 已经弹出内容唤醒生产者继续生产
            System.out.println("get ："+ Arrays.toString(integerArr));
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
